/*
author:杨文超
email:yangwenchao@keynection.cn
*/
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "esp_types.h"
#include "esp_err.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"

/*
Working mode of Modem

*/
typedef enum {
    ESP_MODEM_COMMAND_MODE = 0, /* Command Mode */
    ESP_MODEM_PPP_MODE,         /* PPP Mode */
    ESP_MODEM_TRANSITION_MODE   /* Transition Mode between data and command mode indicating that the modem is not yet ready for sending commands nor data */
} esp_modem_mode_t;

/*
DTE(Data Terminal Equipment)结构体

*/
struct esp_modem_dte {
    esp_modem_flow_ctrl_t flow_ctrl;                                                    /* Flow control of DTE */
    esp_modem_dce_t *dce;                                                               /* DCE which connected to the DTE */
    struct esp_modem_netif_driver_s *netif_adapter;                                     /* Netif adapter */
    SemaphoreHandle_t send_cmd_lock;                                                    /* Mutex for send command */
    esp_err_t (*send_cmd)(esp_modem_dte_t *dte, const char *command, uint32_t timeout); /* Send command to DCE */
    int (*send_data)(esp_modem_dte_t *dte, const char *data, uint32_t length);          /* Send data to DCE */
    esp_err_t (*send_wait)(esp_modem_dte_t *dte, const char *data, uint32_t length,
                           const char *prompt, uint32_t timeout);      /* Wait for specific prompt */
    esp_err_t (*change_mode)(esp_modem_dte_t *dte, esp_modem_mode_t new_mode); /* Changing working mode */
    esp_err_t (*process_cmd_done)(esp_modem_dte_t *dte);                   /* Callback when DCE process command done */
    esp_err_t (*deinit)(esp_modem_dte_t *dte);                             /* Deinitialize */
};

/*
modem接收回调函数

*/
typedef esp_err_t (*esp_modem_on_receive)(void *buffer, size_t len, void *context);

/*
设置modem接收回调函数

@param dte ESP Modem DTE object
@param receive_cb Function pointer to the reception callback
@param receive_cb_ctx Contextual pointer to be passed to the reception callback
@return ESP_OK on success
*/
esp_err_t esp_modem_set_rx_cb(esp_modem_dte_t *dte, esp_modem_on_receive receive_cb, void *receive_cb_ctx);

/**
Notify the modem, that ppp netif has closed
This API should only be used internally by the modem-netif layer
@param dte ESP Modem DTE object

@return ESP_OK on success
*/
esp_err_t esp_modem_notify_ppp_netif_closed(esp_modem_dte_t *dte);

/*
Notify the modem, that all the modem units (DTE, DCE, PPP) has been properly initialized and DTE loop can safely start

@param dte ESP Modem DTE object

@return ESP_OK on success
*/
esp_err_t esp_modem_notify_initialized(esp_modem_dte_t *dte);

/*
 *Configure runtime parameters for the DTE. Currently supports only the baud rate to be set

@param dte ESP Modem DTE object

@return ESP_OK on success
*/
esp_err_t esp_modem_dte_set_params(esp_modem_dte_t *dte, const esp_modem_dte_config_t *config);

#ifdef __cplusplus
}
#endif